home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 1 / Meeting Pearls Vol 1 (1994).iso / installed_progs / util / shell+startup-tools / extracmds / source_etc.lha / src / Count.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-22  |  5.5 KB  |  221 lines

  1. /*
  2.  *  Count - Counts lines, words, and characters.
  3.  *  Copyright (C) 1989, 1991, 1992, 1993 Torsten Poulin
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  The author can be contacted by s-mail at
  20.  *    Torsten Poulin
  21.  *    Banebrinken 99, 2, 77
  22.  *    DK-2400 Copenhagen NV
  23.  *    DENMARK
  24.  *
  25.  * $Id: Count.c,v 37.9 93/06/20 18:52:28 Torsten Rel $
  26.  * $Log:    Count.c,v $
  27.  * Revision 37.9  93/06/20  18:52:28  Torsten
  28.  * Now does its own buffering (32k) in order to speed things up.
  29.  * The effect is quite impressive :-)
  30.  * 
  31.  * Revision 37.8  93/03/01  12:49:37  Torsten
  32.  * Changed all occurrences of "struct DosBase *" to "struct DosLibrary *"
  33.  * 
  34.  * Revision 37.7  93/02/22  18:15:07  Torsten
  35.  * Changed to be linked with the support library
  36.  * 
  37.  * Revision 37.6  93/02/19  18:04:51  Torsten
  38.  * Fixed minor bug in the return code check in entrypoint().
  39.  * 
  40.  * Revision 37.5  93/02/19  02:53:58  Torsten
  41.  * Major rewrite; totally restructured the code.
  42.  * 
  43.  * Revision 37.4  93/02/12  13:19:15  Torsten
  44.  * Moved the source to RCS.
  45.  * Reformatted source.
  46.  * Replaced exec.library/SetSignal() with dos.library/CheckSignal().
  47.  * 
  48.  */
  49.  
  50. #include <exec/types.h>
  51. #include <exec/memory.h>
  52. #include <dos/dos.h>
  53. #include <dos/dosasl.h>
  54. #include <clib/dos_protos.h>
  55. #include <clib/exec_protos.h>
  56. #ifdef __SASC
  57. #include <pragmas/dos_pragmas.h>
  58. #include <pragmas/exec_pragmas.h>
  59. #endif
  60. #include "tastlib.h"
  61. #include "count_rev.h"
  62.  
  63. #define PROGNAME "Count"
  64. #define TEMPLATE "FILE=FROM/M,LINES/S,WORDS/S,BYTES=CHARS/S"
  65. #define OPT_FROM    0
  66. #define OPT_LINES   1
  67. #define OPT_WORDS   2
  68. #define OPT_CHARS   3
  69. #define BUFLEN 32768L
  70.  
  71. char const versionID[] = VERSTAG;
  72. char const copyright[] = "$COPYRIGHT:©1989,1991,1992,1993 Torsten Poulin$";
  73.  
  74. typedef struct {
  75.   struct DosLibrary *DOSBase;
  76.   BOOL lines;
  77.   BOOL words;
  78.   BOOL chars;
  79.   ULONG tl;
  80.   ULONG tw;
  81.   ULONG tc;
  82.   ULONG several;
  83.   UBYTE buffer[BUFLEN];
  84. } Global;
  85.  
  86. LONG count(UBYTE *filename, Global *global);
  87.  
  88.  
  89. LONG entrypoint(VOID)
  90. {
  91.   struct DosLibrary *DOSBase;
  92.   struct RDArgs *args;
  93.   Global *global;
  94.   LONG arg[4];
  95.   LONG rc = RETURN_OK;
  96.  
  97.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
  98.     return RETURN_FAIL;
  99.  
  100.   if (!(global = AllocVec(sizeof(Global), MEMF_PUBLIC | MEMF_CLEAR)))
  101.   {
  102.     PrintFault(ERROR_NO_FREE_STORE, PROGNAME);
  103.     rc = RETURN_FAIL;
  104.     goto OutOfMemory;
  105.   }
  106.   global->DOSBase = DOSBase;
  107.  
  108.   arg[OPT_FROM] = arg[OPT_LINES] = arg[OPT_WORDS] = arg[OPT_CHARS] = 0L;
  109.  
  110.   if (!(args = ReadArgs(TEMPLATE, arg, NULL)))
  111.   {
  112.     printerror(PROGNAME, global);
  113.     rc = RETURN_ERROR;
  114.   }
  115.   else
  116.   {
  117.     if (!arg[OPT_LINES] && !arg[OPT_WORDS] && !arg[OPT_CHARS])
  118.       arg[OPT_LINES] = arg[OPT_WORDS] = arg[OPT_CHARS] = TRUE;
  119.  
  120.     global->lines = (BOOL) arg[OPT_LINES];
  121.     global->words = (BOOL) arg[OPT_WORDS];
  122.     global->chars = (BOOL) arg[OPT_CHARS];
  123.  
  124.     if (!arg[OPT_FROM])
  125.       rc = count(NULL, global);
  126.     else
  127.       rc = foreach((UBYTE **) arg[OPT_FROM], count, global);
  128.     FreeArgs(args);
  129.  
  130.     if (rc == ERROR_BREAK)
  131.     {
  132.       PrintFault(ERROR_BREAK, NULL);
  133.       rc = RETURN_WARN;
  134.     }
  135.     else if (rc == ERROR_NO_FREE_STORE)
  136.     {
  137.       PrintFault(ERROR_NO_FREE_STORE, PROGNAME);
  138.       rc = RETURN_FAIL;
  139.     }
  140.     else if (rc != RETURN_OK)
  141.       printerror(PROGNAME, global);
  142.     else if (global->several > 1)
  143.     {
  144.       if (global->lines) VPrintf("%12ld", (LONG *) &global->tl);
  145.       if (global->words) VPrintf("%12ld", (LONG *) &global->tw);
  146.       if (global->chars) VPrintf("%12ld", (LONG *) &global->tc);
  147.       PutStr(" total\n");
  148.     }
  149.   }
  150.   FreeVec(global);
  151.  OutOfMemory:
  152.   CloseLibrary((struct Library *) DOSBase);
  153.   return rc;
  154. }
  155.  
  156.  
  157. LONG count(UBYTE *filename, Global *global)
  158. {
  159.   struct DosLibrary *DOSBase = global->DOSBase;
  160.   UBYTE *bufp, *bufend;
  161.   LONG  rlen;
  162.   ULONG nc = 0L, nl = 0L, nw = 0L;
  163.   BOOL  inword = FALSE;
  164.   BPTR  fp;
  165.   LONG  c;
  166.  
  167.   bufp = bufend = global->buffer;
  168.   global->several++;
  169.   if (!filename)
  170.     fp = Input();
  171.   else if (!(fp = Open(filename, MODE_OLDFILE)))
  172.   {
  173.     PutStr("Cannot open ");
  174.     printerror(filename, global);
  175.     return RETURN_WARN;
  176.   }
  177.  
  178.   for (;;) {
  179.     if (bufp >= bufend) {
  180.       bufp = global->buffer;
  181.       if ((rlen = Read(fp, bufp, BUFLEN)) <= 0)
  182.         break; /* error or EOF */
  183.       bufend = global->buffer + rlen;
  184.       nc += rlen;
  185.  
  186.       if (CheckSignal(SIGBREAKF_CTRL_C)) {
  187.         if (filename)
  188.       Close(fp);
  189.         return ERROR_BREAK;
  190.       }
  191.     }
  192.  
  193.     c = *bufp++;
  194.     if (c == '\n')
  195.       nl++;
  196.     if (c == ' ' || c == '\t' || c == '\n')
  197.       inword = FALSE;
  198.     else if (!inword)
  199.     {
  200.       inword = TRUE;
  201.       nw++;
  202.     }
  203.   }
  204.  
  205.   global->tl += nl;
  206.   global->tw += nw;
  207.   global->tc += nc;
  208.  
  209.   if (global->lines) VPrintf("%12ld", (LONG *) &nl);
  210.   if (global->words) VPrintf("%12ld", (LONG *) &nw);
  211.   if (global->chars) VPrintf("%12ld", (LONG *) &nc);
  212.   if (filename)
  213.   {
  214.     PutStr(" ");
  215.     PutStr(filename);
  216.     Close(fp);
  217.   }
  218.   PutStr("\n");
  219.   return RETURN_OK;
  220. }
  221.